#ifndef CSIMPLEXUTILS_H_
#define CSIMPLEXUTILS_H_

#include "cmatrix.h"
#include <map>

/**
 * CSimplexUtils - class providing static methods for solving simplex
 * @author Michal Rost
 * @date 05.06.2007
 */
template <typename T>
class CSimplexUtils : public CObject {
public:
  static int solveSimplex(const CMatrix<T> &a, const CVector<T> &b,
                          const CVector<T> &c, int type[], CVector<T> &rc,
                          CVector<T> &rb, T &opt);
  static string getClassName() {
    static const string CLASS_NAME = "CSimplexUtils";
    return CLASS_NAME;
  }
  static const int SIMPLEX_SOLUTION_UNBOUNDED = -1;
  static const int SIMPLEX_SOLUTION_ONE = 0;
  static const int SIMPLEX_SOLUTION_INF = 1;
  static const int CONDITION_LEFT_SIDE_LESSER = -1;
  static const int CONDITION_LEFT_SIDE_EQUAL = 0;
  static const int CONDITION_LEFT_SIDE_GREATER = 1;
private:
  static CMatrix<T> createSimplexTable(const CMatrix<T> &a, const CVector<T> &b,
                                       const CVector<T> &c, int type[],
                                       map<TIndex, TIndex> identColIds,
                                       long &firstFId);
  static CVector<T> createAuxCol(TIndex size, TIndex onePosition,
                                 bool onePositive);
  static bool doSimplex(CMatrix<T> &table, map<TIndex, TIndex> identColIds,
                        TIndex cRowCount);
  static int classifyTable(CMatrix<T> &table, map<TIndex, TIndex> identColIds,
                           TIndex cRowCount, TIndex &pivotRow, 
                           TIndex &pivotCol);
  static void prepareSecondSimplexPhase(CMatrix<T> &table, long firstFId);
  static int getSolutionFromTable(CMatrix<T> &table, 
                                  map<TIndex, TIndex> identColIds,
                                  CVector<T> &rc, CVector<T> &rb, T &opt);
  static const int BLAND_SOLUTION_UNBOUNDED = -1;
  static const int BLAND_SOLUTION_NONOPTIMAL = 0;
  static const int BLAND_SOLUTION_OPTIMAL = 1;
};

#endif
